package cn.ffcs.common.web;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import cn.ffcs.base.web.BaseAction;
import cn.ffcs.bpmpvc.utils.FileUtil;
import cn.ffcs.common.model.Attach;
import cn.ffcs.util.properties.PropertiesUtil;

import com.opensymphony.xwork2.ActionContext;

/**
 * 业务action层<br/> <table>
 * <tr>
 * <td>负责人/principal:</td>
 * <td colspan="2">liuzhh</td>
 * <tr>
 * <td>修改记录/revision:</td>
 * <td colspan="2"></td>
 * </tr>
 * <tr>
 * <td>日期:</td>
 * <td>修改人:</td>
 * <td>修改说明:</td>
 * </tr>
 * <tr>
 * <td></td>
 * <td></td>
 * <td></td>
 * </tr>
 * </table>
 * @author liuzhh
 * @version $Id$
 */
public class AttachAction<A extends Attach> extends BaseAction<A>
{
    /** 日志 * */
    Logger log = Logger.getLogger(this.getClass());

    private static final int BUFFER_SIZE = 16 * 1024;
    /** 业务POJO * */
    private A attach;
    /** 上载文件* */
    public File uploadFile;
    /** 内容 * */
    private String contentType;
    /** 文件名称 * */
    private String fileName;
    /** 输入流 * */
    private ByteArrayInputStream inputStream;
    /** 上传文件 * */
    public File uFile;
    /** 图片显示宽度 * */
    public int imgWidth = 1;
    /** 图片显示高度 * */
    public int imgHeight = 1;

    /**
     * 上载文件
     * @return
     */
    public String uploadFile()
    {
        return SUCCESS;
    }

    /**
     * 保存上载文件
     * @return
     * @throws Exception
     */
    public String saveUploadFile() throws Exception
    {

        byte[] result = new byte[BUFFER_SIZE];
        result = FileUtils.readFileToByteArray(uploadFile);
        FileUtils.forceDelete(uploadFile);

        String fullName = fileName;
        String name = fullName.substring(0, fullName.lastIndexOf("."));
        String prefix = fullName.substring(fullName.lastIndexOf(".") + 1, fullName
                .length());

        attach.setContent(result);
        attach.setFileType("FILE");
        attach.setFullName(fullName);
        attach.setName(name);
        attach.setPrefix(prefix);
        attach.setRefEntity(attach.getClass().getName());
        attach.setRefEntityID("1");
        attach.setIsPublish(1);

        baseService.saveOrUpdate(attach);

        return SUCCESS;
    }

    /**
     * 文件下载
     * @return
     * @throws Exception
     */
    public String showFile() throws Exception
    {
		findById();
		ActionContext ctx = ActionContext.getContext();
		HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
		String fileName = attach.getFullName();
		if(attach.getSaveType()==null||attach.getSaveType()==1){
			//response.setContentType("application/x-download");// 设置为下载application/x-download
			//response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GBK"), "iso8859-1"));
			response.setContentType("application/stream;charset=UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=\""+ URLEncoder.encode(fileName,"UTF-8")+ "\"");
			write(response.getOutputStream(), attach.getContent());
		}else{
			FileUtil.downCommnAttachFile(attach, response);
		}
		return null;
    }

    /**
     * ftp文件下载
     * @return
     * @throws Exception
     */
    public String showFtpFile() throws Exception
    {
        findById();

        String fileName = attach.getFullName();

        ActionContext ctx = ActionContext.getContext();
        HttpServletRequest request = (HttpServletRequest) ctx
                .get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ctx
                .get(ServletActionContext.HTTP_RESPONSE);
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition", "attachment;" + " filename="
                + new String(fileName.getBytes("GBK"), "iso8859-1"));
        try{
            byte[] buffer = new byte[4096]; // 缓冲区
    
            BufferedOutputStream output = null;
            BufferedInputStream input = null;
            String webUrl = ServletActionContext.getServletContext().getRealPath("/");
            String filePath = PropertiesUtil.readValue("/poc-ftp.properties",
                    "ftp.path");
    
            java.io.File f = new java.io.File(webUrl + filePath + "/"
                    + attach.getUrlFileName());
            try
            {
                output = new BufferedOutputStream(response.getOutputStream());
                input = new BufferedInputStream(new FileInputStream(f));
    
                int n = (-1);
                while ((n = input.read(buffer, 0, 4096)) > -1)
                {
                    output.write(buffer, 0, n);
                }
                response.flushBuffer();
            }
            catch (Exception e)
            {
            } // 用户可能取消了下载
            finally
            {
                if (input != null) input.close();
                if (output != null) output.close();
            }
        }catch (Exception e){
            // 如果下载失败了就告诉用户此文件不存在
            e.printStackTrace();
            response.sendError(404);
        }
        return null;
    }

    /**
     * 文件下载
     * @return
     * @throws Exception
     */
    public String showImgFile() throws Exception
    {
        findById();
        String fileName = attach.getFullName();
        ActionContext ctx = ActionContext.getContext();
        HttpServletRequest request = (HttpServletRequest) ctx
                .get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ctx
                .get(ServletActionContext.HTTP_RESPONSE);
        if(attach.getSaveType()==null||attach.getSaveType()==1){
        	write(response.getOutputStream(), attach.getContent());
        }else{
        	 FileUtil.downCommnAttachFile(attach, response);
        }
       

        return null;
    }

    /**
     * 缩小或放大图片
     * @param data 图片的byte数据
     * @param w 需要缩到的宽度
     * @param h 需要缩到高度
     * @return 缩放后的图片的byte数据
     */
    private byte[] ChangeImgSize(byte[] data)
    {
        int nw = this.imgWidth;
        int nh = this.imgHeight;
        byte[] newdata = null;
        try
        {
            BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));
            int w = bis.getWidth();
            int h = bis.getHeight();
            double sx = (double) nw / w;
            double sy = (double) nh / h;
            AffineTransform transform = new AffineTransform();
            transform.setToScale(sx, sy);
            AffineTransformOp ato = new AffineTransformOp(transform, null);
            // 原始颜色
            BufferedImage bid = new BufferedImage(nw, nh,
                    BufferedImage.TYPE_3BYTE_BGR);
            ato.filter(bis, bid);
            // 转换成byte字节
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bid, "jpeg", baos);
            newdata = baos.toByteArray();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        return newdata;

    }

    /**
     * 将图片的以字节形式写到InputStream里
     */
    public ByteArrayInputStream createInputStream() throws Exception
    {

        findById();
        byte[] outResult = ChangeImgSize(attach.getContent());
        ByteArrayInputStream input = new ByteArrayInputStream(outResult);

        return input;
    }

    /**
     * 图片展示
     * @return
     * @throws Exception
     */
    public String showImg() throws Exception
    {
    	return showImgFile();
        //setInputStream(createInputStream());
        //return SUCCESS;
    }

    /**
     * 输出文件内容
     * @param os
     * @param content
     */
    private void write(OutputStream os, byte[] content)
    {
        try
        {
            os.write(content);
            os.flush();
        }
        catch (IOException ex)
        {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 根据关键值获取实体数据
     * @return
     */
    public String findById()
    {
        if (attach != null && attach.getId() != 0)
        {
            attach = (A) baseService.findById(attach.getId());
        }

        return SUCCESS;
    }

    /**
     * 获取文件POJO
     * @return
     */
    public A getAttach()
    {
        return attach;
    }

    /**
     * 设置文件POJO
     * @param attach
     */
    public void setAttach(A attach)
    {
        this.attach = attach;
    }

    /**
     * @return the uploadFile
     */
    public File getUploadFile()
    {
        return uploadFile;
    }

    /**
     * @param uploadFile the uploadFile to set
     */
    public void setUploadFile(File uploadFile)
    {
        this.uploadFile = uploadFile;
    }

    /**
     * @return the uFile
     */
    public File getUFile()
    {
        return uFile;
    }

    /**
     * @param file the uFile to set
     */
    public void setUFile(File file)
    {
        uFile = file;
    }

    public ByteArrayInputStream getInputStream()
    {
        return inputStream;
    }

    public void setInputStream(ByteArrayInputStream inputStream)
    {
        this.inputStream = inputStream;
    }

    public void setUploadFileContentType(String contentType)
    {
        this.contentType = contentType;
    }

    public void setUploadFileFileName(String fileName)
    {
        this.fileName = fileName;
    }

    /**
     * @return the imgWidth
     */
    public int getImgWidth()
    {
        return imgWidth;
    }

    /**
     * @param imgWidth the imgWidth to set
     */
    public void setImgWidth(int imgWidth)
    {
        this.imgWidth = imgWidth;
    }

    /**
     * @return the imgHeight
     */
    public int getImgHeight()
    {
        return imgHeight;
    }

    /**
     * @param imgHeight the imgHeight to set
     */
    public void setImgHeight(int imgHeight)
    {
        this.imgHeight = imgHeight;
    }

}
